00001 /* aes.h */ 00002 00003 /* ---------- See examples at end of this file for typical usage -------- */ 00004 00005 /* AES Cipher header file for ANSI C Submissions 00006 Lawrence E. Bassham III 00007 Computer Security Division 00008 National Institute of Standards and Technology 00009 00010 This sample is to assist implementers developing to the 00011 Cryptographic API Profile for AES Candidate Algorithm Submissions. 00012 Please consult this document as a cross-reference. 00013 00014 ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE 00015 MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH 00016 THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS 00017 CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO 00018 INCLUDE IMPLEMENTATION SPECIFIC INFORMATION. 00019 */ 00020 00021 /* Includes: 00022 Standard include files 00023 */ 00024 00025 #include <stdio.h> 00026 #include "platform.h" /* platform-specific defines */ 00027 00028 /* Defines: 00029 Add any additional defines you need 00030 */ 00031 00032 #define DIR_ENCRYPT 0 /* Are we encrpyting? */ 00033 #define DIR_DECRYPT 1 /* Are we decrpyting? */ 00034 #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ 00035 #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ 00036 #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ 00037 00038 #define TRUE 1 00039 #define FALSE 0 00040 00041 #define BAD_KEY_DIR -1 /* Key direction is invalid (unknown value) */ 00042 #define BAD_KEY_MAT -2 /* Key material not of correct length */ 00043 #define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ 00044 #define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ 00045 #define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ 00046 00047 /* CHANGE POSSIBLE: inclusion of algorithm specific defines */ 00048 /* TWOFISH specific definitions */ 00049 #define MAX_KEY_SIZE 64 /* # of ASCII chars needed to represent a key */ 00050 #define MAX_IV_SIZE 16 /* # of bytes needed to represent an IV */ 00051 #define BAD_INPUT_LEN -6 /* inputLen not a multiple of block size */ 00052 #define BAD_PARAMS -7 /* invalid parameters */ 00053 #define BAD_IV_MAT -8 /* invalid IV text */ 00054 #define BAD_ENDIAN -9 /* incorrect endianness define */ 00055 #define BAD_ALIGN32 -10 /* incorrect 32-bit alignment */ 00056 00057 #define BLOCK_SIZE 128 /* number of bits per block */ 00058 #define MAX_ROUNDS 16 /* max # rounds (for allocating subkey array) */ 00059 #define ROUNDS_128 16 /* default number of rounds for 128-bit keys*/ 00060 #define ROUNDS_192 16 /* default number of rounds for 192-bit keys*/ 00061 #define ROUNDS_256 16 /* default number of rounds for 256-bit keys*/ 00062 #define MAX_KEY_BITS 256 /* max number of bits of key */ 00063 #define MIN_KEY_BITS 128 /* min number of bits of key (zero pad) */ 00064 #define VALID_SIG 0x48534946 /* initialization signature ('FISH') */ 00065 #define MCT_OUTER 400 /* MCT outer loop */ 00066 #define MCT_INNER 10000 /* MCT inner loop */ 00067 #define REENTRANT 1 /* nonzero forces reentrant code (slightly slower) */ 00068 00069 #define INPUT_WHITEN 0 /* subkey array indices */ 00070 #define OUTPUT_WHITEN ( INPUT_WHITEN + BLOCK_SIZE/32) 00071 #define ROUND_SUBKEYS (OUTPUT_WHITEN + BLOCK_SIZE/32) /* use 2 * (# rounds) */ 00072 #define TOTAL_SUBKEYS (ROUND_SUBKEYS + 2*MAX_ROUNDS) 00073 00074 /* Typedefs: 00075 Typedef'ed data storage elements. Add any algorithm specific 00076 parameters at the bottom of the structs as appropriate. 00077 */ 00078 00079 typedef unsigned char BYTE; 00080 typedef unsigned long DWORD; /* 32-bit unsigned quantity */ 00081 typedef DWORD fullSbox[4][256]; 00082 00083 /* The structure for key information */ 00084 typedef struct 00085 { 00086 BYTE direction; /* Key used for encrypting or decrypting? */ 00087 #if ALIGN32 00088 BYTE dummyAlign[3]; /* keep 32-bit alignment */ 00089 #endif 00090 int keyLen; /* Length of the key */ 00091 char keyMaterial[MAX_KEY_SIZE+4];/* Raw key data in ASCII */ 00092 00093 /* Twofish-specific parameters: */ 00094 DWORD keySig; /* set to VALID_SIG by makeKey() */ 00095 int numRounds; /* number of rounds in cipher */ 00096 DWORD key32[MAX_KEY_BITS/32]; /* actual key bits, in dwords */ 00097 DWORD sboxKeys[MAX_KEY_BITS/64];/* key bits used for S-boxes */ 00098 DWORD subKeys[TOTAL_SUBKEYS]; /* round subkeys, input/output whitening bits */ 00099 #if REENTRANT 00100 fullSbox sBox8x32; /* fully expanded S-box */ 00101 #if defined(COMPILE_KEY) && defined(USE_ASM) 00102 #undef VALID_SIG 00103 #define VALID_SIG 0x504D4F43 /* 'COMP': C is compiled with -DCOMPILE_KEY */ 00104 DWORD cSig1; /* set after first "compile" (zero at "init") */ 00105 void *encryptFuncPtr; /* ptr to asm encrypt function */ 00106 void *decryptFuncPtr; /* ptr to asm decrypt function */ 00107 DWORD codeSize; /* size of compiledCode */ 00108 DWORD cSig2; /* set after first "compile" */ 00109 BYTE compiledCode[5000]; /* make room for the code itself */ 00110 #endif 00111 #endif 00112 } keyInstance; 00113 00114 /* The structure for cipher information */ 00115 typedef struct 00116 { 00117 BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ 00118 #if ALIGN32 00119 BYTE dummyAlign[3]; /* keep 32-bit alignment */ 00120 #endif 00121 BYTE IV[MAX_IV_SIZE]; /* CFB1 iv bytes (CBC uses iv32) */ 00122 00123 /* Twofish-specific parameters: */ 00124 DWORD cipherSig; /* set to VALID_SIG by cipherInit() */ 00125 DWORD iv32[BLOCK_SIZE/32]; /* CBC IV bytes arranged as dwords */ 00126 } cipherInstance; 00127 00128 /* Function protoypes */ 00129 int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial); 00130 00131 int cipherInit(cipherInstance *cipher, BYTE mode, char *IV); 00132 00133 int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, 00134 int inputLen, BYTE *outBuffer); 00135 00136 int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, 00137 int inputLen, BYTE *outBuffer); 00138 00139 int reKey(keyInstance *key); /* do key schedule using modified key.keyDwords */ 00140 00141 /* API to check table usage, for use in ECB_TBL KAT */ 00142 #define TAB_DISABLE 0 00143 #define TAB_ENABLE 1 00144 #define TAB_RESET 2 00145 #define TAB_QUERY 3 00146 #define TAB_MIN_QUERY 50 00147 int TableOp(int op); 00148 00149 00150 //#define CONST /* helpful C++ syntax sugar, NOP for ANSI C */ 00151 00152 #if BLOCK_SIZE == 128 /* optimize block copies */ 00153 #define Copy1(d,s,N) ((DWORD *)(d))[N] = ((DWORD *)(s))[N] 00154 #define BlockCopy(d,s) { Copy1(d,s,0);Copy1(d,s,1);Copy1(d,s,2);Copy1(d,s,3); } 00155 #else 00156 #define BlockCopy(d,s) { memcpy(d,s,BLOCK_SIZE/8); } 00157 #endif 00158 00159 00160 #ifdef TEST_2FISH 00161 /* ----- EXAMPLES ----- 00162 00163 Unfortunately, the AES API is somewhat clumsy, and it is not entirely 00164 obvious how to use the above functions. In particular, note that 00165 makeKey() takes an ASCII hex nibble key string (e.g., 32 characters 00166 for a 128-bit key), which is rarely the way that keys are internally 00167 represented. The reKey() function uses instead the keyInstance.key32 00168 array of key bits and is the preferred method. In fact, makeKey() 00169 initializes some internal keyInstance state, then parse the ASCII 00170 string into the binary key32, and calls reKey(). To initialize the 00171 keyInstance state, use a 'dummy' call to makeKey(); i.e., set the 00172 keyMaterial parameter to NULL. Then use reKey() for all key changes. 00173 Similarly, cipherInit takes an IV string in ASCII hex, so a dummy setup 00174 call with a null IV string will skip the ASCII parse. 00175 00176 Note that CFB mode is not well tested nor defined by AES, so using the 00177 Twofish MODE_CFB it not recommended. If you wish to implement a CFB mode, 00178 build it external to the Twofish code, using the Twofish functions only 00179 in ECB mode. 00180 00181 Below is a sample piece of code showing how the code is typically used 00182 to set up a key, encrypt, and decrypt. Error checking is somewhat limited 00183 in this example. Pseudorandom bytes are used for all key and text. 00184 00185 If you compile TWOFISH2.C or TWOFISH.C as a DOS (or Windows Console) app 00186 with this code enabled, the test will be run. For example, using 00187 Borland C, you would compile using: 00188 BCC32 -DTEST_2FISH twofish2.c 00189 to run the test on the optimized code, or 00190 BCC32 -DTEST_2FISH twofish.c 00191 to run the test on the pedagogical code. 00192 00193 */ 00194 00195 #include <stdio.h> 00196 #include <stdlib.h> 00197 #include <time.h> 00198 #include <string.h> 00199 00200 #define MAX_BLK_CNT 4 /* max # blocks per call in TestTwofish */ 00201 int TestTwofish(int mode,int keySize) /* keySize must be 128, 192, or 256 */ 00202 { /* return 0 iff test passes */ 00203 keyInstance ki; /* key information, including tables */ 00204 cipherInstance ci; /* keeps mode (ECB, CBC) and IV */ 00205 BYTE plainText[MAX_BLK_CNT*(BLOCK_SIZE/8)]; 00206 BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE/8)]; 00207 BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE/8)]; 00208 BYTE iv[BLOCK_SIZE/8]; 00209 int i,byteCnt; 00210 00211 if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE) 00212 return 1; /* 'dummy' setup for a 128-bit key */ 00213 if (cipherInit(&ci,mode,NULL) != TRUE) 00214 return 1; /* 'dummy' setup for cipher */ 00215 00216 for (i=0;i<keySize/32;i++) /* select key bits */ 00217 ki.key32[i]=0x10003 * rand(); 00218 reKey(&ki); /* run the key schedule */ 00219 00220 if (mode != MODE_ECB) /* set up random iv (if needed)*/ 00221 { 00222 for (i=0;i<sizeof(iv);i++) 00223 iv[i]=(BYTE) rand(); 00224 memcpy(ci.iv32,iv,sizeof(ci.iv32)); /* copy the IV to ci */ 00225 } 00226 00227 /* select number of bytes to encrypt (multiple of block) */ 00228 /* e.g., byteCnt = 16, 32, 48, 64 */ 00229 byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT)); 00230 00231 for (i=0;i<byteCnt;i++) /* generate test data */ 00232 plainText[i]=(BYTE) rand(); 00233 00234 /* encrypt the bytes */ 00235 if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8) 00236 return 1; 00237 00238 /* decrypt the bytes */ 00239 if (mode != MODE_ECB) /* first re-init the IV (if needed) */ 00240 memcpy(ci.iv32,iv,sizeof(ci.iv32)); 00241 00242 if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8) 00243 return 1; 00244 00245 /* make sure the decrypt output matches original plaintext */ 00246 if (memcmp(plainText,decryptOut,byteCnt)) 00247 return 1; 00248 00249 return 0; /* tests passed! */ 00250 } 00251 00252 void main(void) 00253 { 00254 int testCnt,keySize; 00255 00256 srand((unsigned) time(NULL)); /* randomize */ 00257 00258 for (keySize=128;keySize<=256;keySize+=64) 00259 for (testCnt=0;testCnt<10;testCnt++) 00260 { 00261 if (TestTwofish(MODE_ECB,keySize)) 00262 { printf("ECB Failure at keySize=%d",keySize); return; } 00263 if (TestTwofish(MODE_CBC,keySize)) 00264 { printf("CBC Failure at keySize=%d",keySize); return; } 00265 } 00266 printf("Tests passed"); 00267 } 00268 #endif /* TEST_2FISH */
1.3-rc3